module dice.ui.gadget;

import dice.ui.layout;
import dice.ui.theme;
import dice.ui.container;

import dice.render.painter;
import dice.render.shape;
import dice.render.structs;

import std.stdio;

/* ----- GADGET ---------------------------------------------------- */
class Gadget
{
	/* ----- SIMPLE PROPERTIES ------------------------------------- */
	
	/* Parent */
	/** The containr in which this gadget resides */
	Container parent;
	
	/** True if the parent exists, false otherwise */
	bool hasParent ()
	{
		return parent is null;
	}
	
	/* Theme */
	Theme _theme;
	
	/** Get the gadget's theme */
	Theme theme ()
	{
		if (!(_theme is null))
			return _theme;
		else if (!hasParent)
			return parent.theme;
		else
			return new DefaultTheme;
	}
	
	/** Set the gadget's theme */
	void theme (Theme t)
	{
		_theme = t;
		
	}
	
	/* Theme caching information */
	struct ThemeCache
	{
		void delegate (Gadget g, Painter p) draw;
	}
	
	ThemeCache *themeCache;
	
	/* Shape */
	Shape _shape;
	
	/* Rect */
	Rect _rect;
	
	/** Set the gadget's rectangle (in the co-ordinates of it's container) */
	void rect (Rect r)
	{
		_rect = r;
	}
	
	/** Get the gadget's rectangle (in the co-ordinates of it's container) */
	Rect rect ()
	{
		if (!hasParent)
		{
			parent.ensureLayout();
		}
		return _rect;
	}
	
	/* ContainsMousePosition */
	/** Returns true if the given position is on this widget */
	bool containsMousePosition (float x, float y)
	{
		/+scope Path path;
		if (traceCustomPath(path))
		{
			scope Painter p = Painter.disposable;
			p.trace(path);
			
		}+/
		
		return rect.contains(x, y);
	}
	
	/* ----- DRAWING ----------------------------------------------- */
	/** Draws the gadget on given painter
	 * 
	 *  This uses the theme by default, but can be overriden.
	 */
	void draw (Painter p)
	{
		if (themeCache !is null && themeCache.draw !is null)
		{
			themeCache.draw(this, p);
		}
		else 
		{
			if (themeCache == null)
				themeCache = new ThemeCache;
			
			themeCache.draw = theme.drawDelegateFor(this);
			themeCache.draw(this, p);
		}
	}
	
	/** Sets up this widget's custom path, if available.
	 * 
	 *  Returns true if a custom path was set, or false otherwise.
	 */
	bool traceCustomPath (Painter p)
	{
		return false;
	}
	
	/* ----- MOUSE EVENTS ------------------------------------------ */
	/** Called when the mouse has moved inside this gadget */
	void mouseMotion (float x, float y)
	{
		writefln("MOVE %s %s", x, y);
	}
} 
